package com.xiaoxie.mapper;


import com.xiaoxie.DTO.PageDTO;
import com.xiaoxie.DTO.modifyWordDTO;
import com.xiaoxie.DTO.quick_chooseDTO;
import com.xiaoxie.DTO.wordUpdateDTO;
import com.xiaoxie.entity.Word;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * <p>
 * Mapper 接口
 * </p>
 *
 * @author 小谢
 * @since 2023-10-13
 */
@Mapper
public interface WordDao {
    @Select("select * from word_tb where user=#{account} and word=#{wordDTO.word}")
    List<Word> getBy(wordUpdateDTO wordDTO,String account);
    @Select("select * from word_tb where word=#{wordDTO.word} and user=#{account}")
    Word getByword(wordUpdateDTO wordDTO,String account);
    @Select("select * from word_tb where id=#{id}")
    Word getById(Integer id);
    /**
     * 首先，根据单词的熟悉程度（familiar）和下次复习时间（nextTime）来选择今天需要记忆的单词。这里假设你使用的是0-100的熟悉程度评分，0表示完全不熟悉，100表示非常熟悉。
     * <p>
     * SELECT * FROM Word
     * WHERE nextTime <= CURRENT_TIMESTAMP -- 下次复习时间在当前时间或之前
     * AND familiar < 100 -- 熟悉程度小于100
     * ORDER BY familiar ASC, nextTime ASC -- 按照熟悉程度升序、下次复习时间升序排列
     * LIMIT N; -- 返回前N个单词
     *
     * @return
     */
    @Select("SELECT * FROM word_tb WHERE `user` = #{account} and DATE(nextTime) <= CURDATE() AND strength < 100 ORDER BY RAND()")
    List<Word> getNeedMemory(String account);

    /**
     * 单词记忆错误
     * wrong = wrong + 1：将原本记录的答错次数加1。
     * familiar = right / (right + wrong + 1)：根据答对次数和答错次数计算熟悉度。
     * strength = strength - 1：将原本记录的记忆强度减1。
     * interval = 1：将记忆间隔重置为1。即，答错后立即进行下一次复习。
     * lastTime = NOW()：将最后一次复习时间更新为当前时间。
     * nextTime = DATE_ADD(NOW(), INTERVAL 1 DAY)：将下次复习的时间设置为当前时间加1天。
     *
     * @param wordDTO
     */
    @Update("UPDATE `word_tb` " +
            "SET `wrong` = `wrong` + 1," +
            "    `familiar` = `right` / (`right` + `wrong` + 1)," +
            "    `strength` = `strength` - 1," +
            "    `interval` = 1," +
            "    `lastTime` = NOW()," +
            "     learn_today=learn_today+1,"+
            "    `nextTime` = DATE_ADD(NOW(), INTERVAL 1 DAY)," +
            "   wrong_today = wrong_today+1 " +
            "WHERE `word` = #{wordDTO.word} AND `user` = #{account};")
    void wrong(wordUpdateDTO wordDTO,String account);

    /**
     * 单词记忆正确
     * right = right + 1：将原本记录的答对次数加1。
     * familiar = (right + 1) / (right + wrong + 2)：根据答对次数和答错次数计算熟悉度。公式中的+1和+2是为了避免除数为0的情况，确保计算的准确性。
     * strength = strength + 1：将原本记录的记忆强度加1。
     * interval = CASE WHEN interval = 1 THEN 2 ELSE interval * 2 END：根据记忆间隔的当前值进行判断，如果当前值为1，则将其更新为2；否则将当前值乘以2。这个逻辑可以根据实际需求进行自定义。
     * lastTime = NOW()：将最后一次复习时间更新为当前时间。
     * nextTime = DATE_ADD(NOW(), INTERVAL interval DAY)：根据记忆间隔计算出下次复习的时间。将当前时间加上记忆间隔的天数，得到下次复习的时间。
     *
     * @param wordDTO //数据响应模型
     */

    @Update("UPDATE `word_tb` \n" +
            "SET `right` = `right` + 1,\n" +
            "    `familiar` = (`right` + 1) / (`right` + `wrong` + 1),\n" +
            "    `strength` = `strength` + 1,\n" +
            "    `interval` = CASE \n" +
            "                    WHEN `interval` = 1 THEN 2\n" +
            "                    ELSE `interval` * 2\n" +
            "               END,\n" +
            "    `lastTime` = NOW(),\n" +
            "     learn_today=learn_today+1,"+
            "    `nextTime` = DATE_ADD(NOW(), INTERVAL `interval` *`familiar` DAY)" +
            "WHERE `word` = #{wordDTO.word} AND `user` = #{account};")
    void right(wordUpdateDTO wordDTO,String account);

    /**
     * 查询今日错误单词
     * @return
     */
    @Select("select * from word_tb where wrong_today>0.01 and user=#{account} ORDER BY RAND()")
    List<Word> getwrong(String account);

    /**
     * 用户完成学习，复习单词错误，次数+1
     *
     * @param wordDTO
     */
    @Update("update word_tb set learn_today=learn_today+1,wrong_today=word_tb.wrong_today-0.2 where user=#{account} and `word` = #{wordDTO.word}")
    void rightFinish(wordUpdateDTO wordDTO,String account);

    /**
     * 用户完成学习，复习单词真确，错误次数-1
     *
     * @param wordDTO
     */
    @Update("update word_tb set learn_today=learn_today+1,wrong_today=word_tb.wrong+1 where user=#{account} and `word` = #{wordDTO.word}")
    void wrongFinish(wordUpdateDTO wordDTO ,String account);

    /**
     * 添加单词
     *
     * @param wordDTO
     */
    @Insert("INSERT INTO word_tb  " +
            "VALUES (null,#{wordDTO.word}, #{account},#{wordDTO.meaning}," +
            "now(),0, 0, 0, 'false', 0, 1.0,now(),0,#{wordDTO.lexiconID},0);")
    void insert(wordUpdateDTO wordDTO,String account);

    @Update("update word_tb set learn_today=0,wrong_today=0 where user=#{account}")
    void initWrong(String account);


    List<Word> pageList(PageDTO pageDTO, String currentAccount);

    @Select("select * from word_tb where user=#{account}")
    List<Word> getAll(String account);

    @Update("update word_tb set word=#{word} ,meaning=#{meaning}  where id=#{id}")
    void modifyWord(modifyWordDTO wordDTO);

    @Delete("delete from word_tb where id=#{id}")
    void delete(Integer id);

    /**
     * 单词速刷获取数据
     * @param account
     * @return
     */
    @Select("select id,word,meaning from word_tb where user=#{account}  order by familiar limit 100 ")
    List<quick_chooseDTO> quick_Choose(String account);

    @Update("update word_tb set learn_today=learn_today+1,strength=strength+1 , `right` = `right`+0.3 ,`familiar` = (`right` + 1) / (`right` + `wrong` + 1) where id=#{id}")
    void quickRight(Integer id);
    @Update("update word_tb set learn_today=learn_today+1,strength=strength-1, `wrong` = `wrong`+1 , `familiar` = (`right` + 1) / (`right` + `wrong` + 1) where id=#{id}")
    void quickWrong(Integer id);
}
